import { Component, OnInit, EventEmitter, HostListener } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { NzModalService } from 'ng-zorro-antd'
import * as moment from 'moment'
import 'String.prototype.at'
import { Observable } from 'rxjs/Observable'
import { Store } from '@ngrx/store'
import * as fromRoot from '../../core/reducers'
import * as fromChecklist from '../../core/actions/checklist'

import { ITask, IOptionMenu } from '../../core/models'
import { INewTaskDto, IRenameTitleDto, IContextTaskDto, IUpdateTaskDto, IShowFinishedDto } from '../../core/dtos'
import { Functions } from '../../common/functions'
import { KEY_CODE } from '../../common/keycodes'

@Component({
  selector: 'app-todo',
  templateUrl: './todo.component.html',
  styleUrls: [
    './todo.component.less',
    '../../common/new-todo.less',
    '../../common/todo-list.less'
  ]
})

export class TodoComponent implements OnInit {
  tasks: ITask[]
  isChecklistStatic: boolean  // 控制改变选项菜单项
  checklistTitle: string
  newTodo: string
  currentListId: string
  focused = false  // 控制添加待办事项的样式
  isTitleClicked = false // 控制标题的样式
  isDetailDisplayed = false  // 控制右边详情栏是否显示
  optionMenu: IOptionMenu = {
    show: false,
    type: 0,
    showFinished: false
  } // 控制标题附件的选项菜单是否显示

  renameTitleEvent = new EventEmitter<any>()

  currentItem: IContextTaskDto
  contextmenuVisible = false
  contextmenuX = 0
  contextmenuY = 0

  constructor (
    private _store: Store<fromRoot.IState>,
    private _confirm: NzModalService,
    private _router: ActivatedRoute,
    private _funcs: Functions) { }

  ngOnInit (): void {
    const checklistsStore = this._store.select(fromRoot.selectChecklists)
    // after addNewTask success, clear newTodo input
    checklistsStore.subscribe((lists) => {
      this.newTodo = null
      if (this.currentListId) {
        const currentList = lists.find((v) => v.id === this.currentListId)
        this.tasks = currentList.showFinished
          ? currentList.tasks
          : currentList.tasks.filter((u) => u.isDone === false)
        this.optionMenu.showFinished = currentList.showFinished
      }
    })
    // router changed
    this._router.params.subscribe(({ id }) => {
      this.currentListId = id
      this.isDetailDisplayed = false
      checklistsStore
        .select((u) => u.length > 0 && u.find((v) => v.id === id))
        .subscribe((list) => {
          if (!list) return // after deleted the checklist need this
          this.checklistTitle
            = this._funcs.isDefaultIcon(list.icon)
            ? list.title
            : list.icon + list.title
          this.isChecklistStatic = list.isStatic
          this.tasks = list.showFinished
            ? list.tasks
            : list.tasks.filter((u) => u.isDone === false)

          this.optionMenu.showFinished = list.showFinished
        })

      // 监听url参数(newlist) 即 监听新建清单操作
      this._router.queryParams.subscribe(({ newlist }) => {
        if (Boolean(newlist)) {
          this.isTitleClicked = true
          this.renameTitleEvent.emit(null)
        }
      })
    })
  }

  clickTitle () {
    if (!this.isChecklistStatic) {
      this.isTitleClicked = true
      this.renameTitleEvent.emit(null)
    }
  }

  rename () {
    this.isTitleClicked = false
    const payload: IRenameTitleDto = {
      id: this.currentListId,
      title: this.checklistTitle,
      icon: 'list'
    }
    console.log(payload.title)
    // tslint:disable-next-line:max-line-length
    const regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/g
    const char = (payload.title as any).at(0)  // to solve the ts lint
    if (regex.test(char)) {
      // * 如果第一个字符是emoji
      payload.title = payload.title.substring(2)
      payload.icon = char
    }
    this._store.dispatch(new fromChecklist.RenameChecklistAction(payload))
  }

  // 添加待办项目
  addNewTask () {
    if (this.newTodo && this.newTodo.trim()) {
      const newTask: INewTaskDto = {
        todo: this.newTodo.trim(),
        listId: this.currentListId
      }
      this._store.dispatch(new fromChecklist.AddNewTaskAction(newTask))
    }
  }

  // * 监听键盘事件
  // * https://coryrylan.com/blog/listening-to-angular-key-events-with-host-listeners
  @HostListener('window: keyup', ['$event'])
  KeyEvent (event: KeyboardEvent) {
    if (event.keyCode === KEY_CODE.ENTER) {
      if (this.isTitleClicked) {
        this.rename()
      } else {
        this.addNewTask()
      }
    }
  }

  // 今日任务输入框聚焦与blur
  focus (): void {
    this.focused = true
  }
  blur (): void {
    setTimeout(() => {
      this.focused = false
    }, 300)
  }

  // 点击图标toggleDone
  toggleDone (task: ITask, event: MouseEvent) {
    event.stopPropagation()
    const { index, isDone } = task
    const dto: IUpdateTaskDto = {
      listId: this.currentListId,
      index,
      ['isDone']: !isDone
    }
    this._store.dispatch(new fromChecklist.ToggleDoneTaskActin(dto))
  }

  handleContextmenu (e: MouseEvent, item) {
    this.currentItem = item
    this.currentItem.listId = this.currentListId
    this.contextmenuVisible = true
    this.contextmenuX = e.clientX
    this.contextmenuY = e.clientY
    e.preventDefault()
  }

  @HostListener('document:click') closeContextmenu () {
    this.contextmenuVisible = false
    this.optionMenu.show = false
    this.optionMenu.type = 0
  }

  openDetail (task: ITask) {
    this.isDetailDisplayed = true
    this.currentItem = task
    this.currentItem.listId = this.currentListId
  }

  changeDetail (task: ITask) {
    this.currentItem = task
    this.currentItem.listId = this.currentListId
  }

  onHideDetail (isHide: boolean) {
    this.isDetailDisplayed = !isHide
  }

  renderDeadlineStyle (value: string, isDone: boolean) {
    if (isDone) { return }
    const deadline = moment(value.substring(0, 10))
    const now = moment(moment().format('YYYY-MM-DD'))
    return deadline.diff(now) >= 0
      ? '#465efc'
      : '#fc4646'
  }

  showOptionMenu (event: MouseEvent, type: number) {
    this.optionMenu.show = true
    this.optionMenu.type = type
    event.stopPropagation()
  }

  toggleShowDoneTasks (show) {
    const dto: IShowFinishedDto = {
      listId: this.currentListId,
      show: !show
    }
    this._store.dispatch(new fromChecklist.ToggleShowFinishedAction(dto))
  }

  deleteList () {
    const ctx = this
    this._confirm.confirm({
      title: '您确定要删除该清单吗？',
      content: '删除后无法恢复，请谨慎！',
      onOk: () => {
        ctx._store.dispatch(new fromChecklist.DeleteChecklistAction(ctx.currentListId))
      }
    })
  }
}
